本篇文章同步更新於個人部落格,歡迎交流指教~謝謝您的閱讀
@nuxtjs/i18n 版本:v8.0.0-rc.3
多國語系讓我們的網站邁向國際市場,本篇將說明如何搭配 Nuxt3 整合模組 @nuxtjs/i18n 進行開發
Nuxt3 需搭配 v8 版本,目前為 rc 版,透過 next
tag 安裝
npm install -D @nuxtjs/i18n@next
// nuxt.config.js
export default defineNuxtConfig({
modules: [
'@nuxtjs/i18n',
]
})
i18n module 完整選項參考 官方文件,以下範例配置:
strategy: 定義路由是否加上語系前綴,範例使用 prefix
,所有語系都會加上路徑前綴(ex: http://localhost:3000/zh/
)
langDir: 翻譯檔目錄路徑,範例為根目錄下 locales/
資料夾
locales: 語系選項,範例設定繁體中文跟英文,存放於 langDir
目錄下,以下範例檔結構:
locales/
|—— en.js
|—— zh.js
nuxt.config.js
defaultLocale: 預設語系
detectBrowserLanguage: 是否自動偵測使用者瀏覽器語系
true
將語系儲存於 cookie,避免使用者每次進入網站都重新導向i18n_redirected
root
根目錄,只在根目錄偵測語系,避免使用者進入網站時被重新導向,以利 SEO// nuxt.config.js
export default defineNuxtConfig({
i18n: {
strategy: 'prefix',
langDir: 'locales',
locales: [
{
code: 'en',
iso: 'en-US',
file: 'en.js'
},
{
code: 'zh',
iso: 'zh-TW',
file: 'zh.js'
}
],
defaultLocale: 'zh',
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root'
}
}
})
路徑結構:
locales/
|—— en.js
|—— zh.js
// locales/en.js
export default {
welcome: 'Welcome',
backHome: 'Back Home',
about: {
title: 'About Us',
description: 'This is About Page'
}
};
// locales/zh.js
export default {
welcome: '您好',
backHome: '回首頁',
about: {
title: '關於我們',
description: '這是關於我們頁面'
}
};
useLocalePath
:依據當前語系解析路徑,EX:/about
→ /zh/about
useSwitchLocalePath
:用來切換語系$t
:Vue 實體方法,用來翻譯訊息// pages/about.vue
<template>
<div class="m-4">
<NuxtLink :to="localePath('/')">{{ $t('backHome') }}</NuxtLink>
<div>
<NuxtLink :to="switchLocalePath('en')">English</NuxtLink>
<NuxtLink :to="switchLocalePath('zh')">繁體中文</NuxtLink>
</div>
<h2>{{ $t('welcome') }}</h2>
<h3>{{ $t('about.title') }}</h3>
<p>{{ $t('about.description') }}</p>
</div>
</template>
<script setup>
const localePath = useLocalePath();
const switchLocalePath = useSwitchLocalePath();
</script>
畫面呈現如下:
前面說明如何建立各語系翻譯檔,也可以單獨在元件內透過 <i18n>
定義翻譯資訊
useScope: 'local'
將 t
方法作用域限制於元件內,這麼做可以避免受到全域翻譯檔影響
// pages/about.vue
<template>
<div class="m-4">
元件翻譯
<h2>{{ t('welcome') }}</h2>
全域翻譯
<h2>{{ $t('welcome') }}</h2>
</div>
</template>
<i18n lang="yaml">
en:
welcome: 'hello world'
zh:
welcome: '哈囉世界'
</i18n>
<script setup>
const { t } = useI18n({
useScope: 'local'
});
</script>
全域翻譯檔
// locales/zh.js
export default {
welcome: '您好'
};
畫面呈現如下:
// pages/about.vue
<template>
<h1>{{ t('hello', { name: 'Daniel' }) }}</h1>
</template>
<i18n lang="yaml">
en:
hello: 'hello {name}'
zh:
hello: '哈囉 {name}'
</i18n>
<script setup>
const { t } = useI18n({
useScope: 'local'
});
</script>
// pages/about.vue
<template>
<h1>{{ t('hello', [ 'Daniel' ]) }}</h1>
</template>
<i18n lang="yaml">
en:
hello: 'hello {0}'
zh:
hello: '哈囉 {0}'
</i18n>
// ...
<NuxtLinkLocale>
元件等同於 <NuxtLink>
搭配 useLocalePath()
Composable,以下兩個寫法編譯後結果相同
<template>
<NuxtLinkLocale to="/">{{ $t('home') }}</NuxtLinkLocale>
</template>
<template>
<NuxtLink :to="localePath('/')">{{ $t('home') }}</NuxtLink>
</template>
<script setup>
const localePath = useLocalePath();
</script>
透過 useLocaleHead()
優化多國語系的 <head>
設定:
useLocaleHead
:依據當前語系回傳 head 屬性
<html>
標籤 lang
屬性hreflang
標籤屬性:告訴搜尋引擎頁面使用的語言,讓使用者在搜尋時,搜尋引擎能提供對應語言給用戶og:locale
以及 og:locale:alternate
標籤addSeoAttributes
:是否加上 SEO 屬性useHead
:Nuxt Composable,用來定義完整 <head>
標籤內容Nuxt3 meta tags 相關配置可以參考 D16文章
// pages/about.vue
<template>
<div>...</div>
</template>
<script setup>
const i18nHead = useLocaleHead({
addSeoAttributes: true
});
useHead({
htmlAttrs: {
lang: i18nHead.value.htmlAttrs.lang
},
link: [ ...(i18nHead.value.link || []) ],
meta: [ ...(i18nHead.value.meta || []) ]
});
</script>
產生的網頁原始碼:
參考資源:
https://v8.i18n.nuxtjs.org/
https://vue-i18n.intlify.dev/